<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head th:include="/common/common :: headVue('聊天室')"></head>

<style>
    body {
        background-color: #ECECEC;
        overflow: hidden;
    }

    .box-card {
        margin-bottom: 10px;
    }

    .text {
        font-size: 14px;
    }

    .item {
        margin-bottom: 18px;
    }

    .clearfix:before,
    .clearfix:after {
        display: table;
        content: "";
    }
    .clearfix:after {
        clear: both
    }

    ::-webkit-scrollbar {
        width: 15px;
        height: 15px;
    }

    /* 谷歌浏览器滚动条美化 */
    ::-webkit-scrollbar-track,
    ::-webkit-scrollbar-thumb {
        border-radius: 999px;
        border: 5px solid transparent;
    }

    ::-webkit-scrollbar-track {
        box-shadow: 1px 1px 5px rgba(143, 143, 143, 0.2) inset;
    }

    ::-webkit-scrollbar-thumb {
        min-height: 20px;
        background-clip: content-box;
        box-shadow: 0 0 0 5px rgba(143, 143, 143, 0.466) inset;
    }

    ::-webkit-scrollbar-corner {
        background: transparent;
    }
</style>
<body>

    <div id="app">
        <el-row :gutter="20">
            <el-col :span="12" :offset="6">
                <el-card shadow="hover" class="box-card">
                    <div slot="header" class="clearfix">
                        <span>消息列表</span>
                        <el-button v-show="logOutShowFlag" style="float: right; padding: 3px 0" @click="logOut" type="text">注销</el-button>
                        <el-button style="float: right; padding: 3px 8px" @click="cleanMsg" type="text">清空消息</el-button>
                    </div>
                    <div id="msgList" style="overflow: auto;height: 450px;">
                        <div v-for="msg in msgList" :key="msg" class="text item">
                            <b>{{ msg.msgDate }}</b>&nbsp;
                            <span v-if="msg.msgType == '00'"><span style='color: blue;'>{{ msg.sourceUserName }}</span><b>: </b>{{ msg.msgContent }}</span>
                            <span v-if="msg.msgType == '01'" style='color: blue'>{{ msg.sourceUserName }}进入了聊天室</span>
                            <span v-if="msg.msgType == '02'" style='color: gray'>{{ msg.sourceUserName }}离开了聊天室</span>
                        </div>
                    </div>
                </el-card>
                <el-card shadow="hover" class="box-card">
                    <el-row :gutter="10">
                        <el-col :span="21">
                            <el-input v-model.trim="msgContent" placeholder="请输入内容" @keyup.enter.native="sendMsg" clearable="true"></el-input>
                        </el-col>
                        <el-col :span="3">
                            <el-button type="primary" :loading="sendLoading" @click="sendMsg">发送</el-button>
                        </el-col>
                    </el-row>
                </el-card>
            </el-col>
        </el-row>
    </div>

    <script type="text/javascript" th:inline="javascript">
        /*<![CDATA[*/
        var myApp = new Vue({
            el: '#app',
            data: {
                // 按钮加载条控制
                sendLoading: false,
                // 当前用户名
                userName: '',
                // 当前用户名
                socket: null,
                // 消息类型
                msgType: '00',
                // 消息数据
                msgContent: '',
                // 消息列表
                msgList: [],
                // 注销按钮是否显示
                logOutShowFlag: false
            },
            // 启动时就执行
            mounted: function() {
                // 获取Cookie的UserName
                var userName = getCookie('00-Netty-SocketIO-UserName');
                if (userName) {
                    // 存在直接连接
                    this.userName = userName;
                    this.connect();
                } else {
                    // 不存在需要输入用户名
                    this.getUser();
                }
            },
            methods: {
                // 输入用户名
                getUser() {
                    this.$prompt('请输入用户名进入聊天室', '提示', {
                        closeOnClickModal: false,
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        inputValidator: function (value) {
                            if (value) {

                            } else {
                                return "用户名不能为空";
                            }
                        },
                    }).then(({value}) => {
                        this.userName = value;
                        setCookie('00-Netty-SocketIO-UserName', this.userName, 1);
                        this.connect();
                    }).catch(() => {
                        this.$message({
                            type: 'info',
                            message: '取消输入'
                        });
                    });
                },
                // 连接Socket
                connect() {
                    this.logOutShowFlag = true;
                    this.socket = io.connect("localhost:9090", {
                        'query': 'userName=' + this.userName,
                        // 放弃之前尝试重新连接的次数，默认值 Infinity
                        'reconnectionAttempts': 3,
                        // 每次连接等待时间 默认值 1000
                        'reconnectionDelay': 3000
                    });
                    // 监听receiveMsg接收消息事件
                    this.socket.on('receiveMsg', (data) => {
                        // console.log(data);
                        data.msgDate = moment().format('HH:mm:ss');
                        if (data.msgType == '00') {
                            // 发送消息给全部人
                            this.$notify({
                                dangerouslyUseHTMLString: true,
                                title: data.sourceUserName,
                                message: '<b>在' + data.msgDate + '说' + data.msgContent + '</b>',
                                duration: 6000
                            });
                        } else if (data.msgType == '01') {
                            // 上线通知
                            this.$notify({
                                dangerouslyUseHTMLString: true,
                                title: data.sourceUserName,
                                message: data.msgDate + '<b>进入了聊天室</b>',
                                duration: 6000
                            });
                        } else if (data.msgType == '02') {
                            // 下线通知
                            this.$notify({
                                dangerouslyUseHTMLString: true,
                                title: data.sourceUserName,
                                message: data.msgDate + '<b>离开了聊天室</b>',
                                duration: 6000
                            });
                        }
                        this.msgList.push(data);
                        this.$nextTick(() => {
                            var msgListDiv = document.getElementById('msgList');
                            msgListDiv.scrollTop = msgListDiv.scrollHeight;
                        });
                    });
                    /*this.$notify({
                        dangerouslyUseHTMLString: true,
                        title: this.userName,
                        message: '<b>欢迎来到聊天室</b>',
                        duration: 0
                    });*/
                },
                // 发送消息
                sendMsg() {
                    if (this.userName) {
                        this.sendLoading = true;
                        // 消息不能为空
                        if (this.msgContent) {
                            this.socket.emit('sendMsg', {
                                "sourceUserName": this.userName,
                                "msgType": this.msgType,
                                "msgContent": this.msgContent
                            });
                        } else {
                            this.$message.error("消息不能为空");
                        }
                        this.msgContent = '';
                        this.sendLoading = false;
                    } else {
                        this.getUser();
                    }
                },
                // 清空消息
                cleanMsg() {
                    // this.$nextTick Dom渲染完执行
                    this.$nextTick(() => {
                        this.$confirm('你确定清空消息吗', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            this.msgList = [];
                        });
                    });
                },
                // 注销
                logOut() {
                    // 删除Cookie
                    delCookie('00-Netty-SocketIO-UserName');
                    // 刷新页面
                    document.location.reload();
                }
            }
        })
        /*]]>*/

        /**
         * 设置Cookie
         * @param cname
         * @param cvalue
         * @param exdays
         */
        function setCookie(cname, cvalue, exdays) {
            var d = new Date();
            d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
            var expires = "expires=" + d.toGMTString();
            document.cookie = cname + "=" + cvalue + "; " + expires;
        }

        /**
         * 获取Cookie
         * @param cname
         * @returns {string}
         */
        function getCookie(cname) {
            var name = cname + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i].trim();
                if (c.indexOf(name) == 0) {
                    return c.substring(name.length, c.length);
                }
            }
            return "";
        }

        /**
         * 删除Cookie
         * @param cname
         */
        function delCookie(cname) {
            var exp = new Date();
            exp.setTime(exp.getTime() - 1);
            var cval = getCookie(cname);
            if (cval) {
                document.cookie = cname + "=" + cval + ";expires=" + exp.toGMTString();
            }
        }

    </script>

</body>

</html>